%%%-------------------------------------------------------------------
%% @doc mqeg_consumer public API
%% @end
%%%-------------------------------------------------------------------

-module(mqeg_consumer).
-behaviour(gen_server).

-include("debug.hrl").
-include_lib("amqp_client/include/amqp_client.hrl").

%% --------------------------------------------------------------------
%% External exports
%% --------------------------------------------------------------------
-export([start_link/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state, {connection, channel, queue, routing_key, basic_consume, consumer_tag}).
%% ====================================================================
%% External functions
%% ====================================================================
start_link(Name) ->
    gen_server:start_link(?MODULE, Name, []).


%% ====================================================================
init(Name) ->
    ?trace("mqeg_consumer Name: ~p", [Name]),
    BasicConsume    = basic_consume(Name),
    Consumer        = self(),

    Connection      = mqeg_misc:get_singleton(connection),
    {ok, Channel}   = amqp_connection:open_channel(Connection),

    #'basic.consume_ok'{consumer_tag = Tag} = amqp_channel:subscribe(Channel, BasicConsume, Consumer),

    {ok, #state{ connection       = Connection
               , channel          = Channel
               , queue            = Name
               , routing_key      = Name
               , basic_consume    = BasicConsume
               , consumer_tag     = Tag
               }
    }.


handle_call(_Info, _From, State) ->
    ?trace(_Info),
    {reply, ok, State}.


handle_cast(stop, State) ->
    {stop, normal, State};

handle_cast(show, State) ->
    ?trace("connection: ~p; "
           "channel: ~p; "
           "queue: ~p; "
           "routing_key: ~p; "
           "basic_consume: ~p; "
           "consumer_tag: ~p; "
          , tl( tuple_to_list(State) )),
    {noreply, State};

handle_cast(_Info, State) ->
    ?trace(_Info),
    {noreply, State}.

handle_info({BasicDeliver, AmqpMsg}, State) ->
    catch ?trace( "consumer_tag: ~p, "
                  "routing_key: ~p, "
                  "payload: ~p",
                  [ BasicDeliver#'basic.deliver'.consumer_tag
                  , BasicDeliver#'basic.deliver'.routing_key
                  , AmqpMsg#amqp_msg.payload]),
    {noreply, State};

handle_info(_Info, State) ->
    ?trace(_Info),
    {noreply, State}.


terminate(_Reason, State) ->
    amqp_channel:call(State#state.channel, #'basic.cancel'{consumer_tag = State#state.consumer_tag}),
    amqp_channel:close(State#state.channel),
    mqeg_consumers_sup:del_consumer(State#state.queue),
    ok.


code_change(_oldvsn, Status, _extra) ->
    {ok, Status}.


%% ====================================================================
%% Local functions
%% ====================================================================
basic_consume(Name) ->
    #'basic.consume'{ queue = Name }.
